<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Echarts Graph</title>

    <!-- unpkg.com 国内镜像 unpkg.zhimg.com -->

    <!-- vue2 -->
    <script src="../../modules/vue@2/dist/vue.js"></script>

    <!-- 引入网络 -->
    <script src="../../modules/axios-1.1.3/axios-1.1.3.min.js"></script>


    <!-- element-ui -->
    <!-- 引入样式 -->
    <link rel="stylesheet" href="../../modules/element-ui@2.15.13/lib/theme-chalk/index.css">
    <!-- 引入组件库 -->
    <script src="../../modules/element-ui@2.15.13/lib/index.js"></script>

    <script src="../../modules/echarts@5.5.1/dist/echarts.min.js"></script>
</head>
<body>
<div id="app">
    <div id="chart" style="display: block;width: 100%;height: 100vh;">

    </div>
    <div>
        <el-row>
            <el-button size="mini" type="primary" @click="onClearLastState">还原默认</el-button>
        </el-row>
        <el-row>
            <el-input v-model="graphJson"
                      @keyup.enter.native="renderChart"
                      type="textarea"
                      :rows="50"
                      @change="renderChart"
                      placeholder="graph的JSON数据"></el-input>
        </el-row>
    </div>
</div>
</body>
<script>

    // 定义默认的参数
    axios.defaults.headers['Content-Type'] = 'application/json'

    Vue.prototype.$axios = axios.create({
        baseURL: 'http://localhost:8080',
        timeout: 30 * 60 * 1000,
        responseType: 'json'
    })

    Vue.prototype.$echarts = echarts

    const defaultGraph=
        {"categories":[{"name":"CLASS"},{"name":"FIELD"},{"name":"METHOD"},{"name":"CONSTRUCTOR"},{"name":"INTERFACE"},{"name":"SUPER"},{"name":"ANNOTATION"},{"name":"PARAMETER"},{"name":"RETURN"},{"name":"EXCEPTION"}],"links":[{"source":17,"target":3,"value":"FIELD"},{"source":3,"target":17,"value":"REAL"},{"source":17,"target":15,"value":"FIELD"},{"source":15,"target":17,"value":"REAL"},{"source":17,"target":0,"value":"FIELD"},{"source":0,"target":17,"value":"REAL"},{"source":17,"target":1,"value":"FIELD"},{"source":1,"target":17,"value":"REAL"},{"source":17,"target":13,"value":"FIELD"},{"source":13,"target":17,"value":"REAL"},{"source":17,"target":26,"value":"FIELD"},{"source":26,"target":17,"value":"REAL"},{"source":17,"target":22,"value":"FIELD"},{"source":22,"target":17,"value":"REAL"},{"source":17,"target":18,"value":"FIELD"},{"source":18,"target":17,"value":"REAL"},{"source":17,"target":4,"value":"FIELD"},{"source":4,"target":17,"value":"REAL"},{"source":17,"target":7,"value":"FIELD"},{"source":7,"target":17,"value":"REAL"},{"source":17,"target":12,"value":"FIELD"},{"source":12,"target":20,"value":"REAL"},{"source":17,"target":2,"value":"FIELD"},{"source":2,"target":10,"value":"REAL"},{"source":17,"target":25,"value":"FIELD"},{"source":25,"target":8,"value":"REAL"},{"source":8,"target":24,"value":"SUPER"},{"source":8,"target":16,"value":"INTERFACE"},{"source":8,"target":21,"value":"INTERFACE"},{"source":17,"target":23,"value":"METHOD"},{"source":23,"target":8,"value":"RETURN"},{"source":17,"target":6,"value":"METHOD"},{"source":6,"target":10,"value":"PARAMETER"},{"source":6,"target":17,"value":"RETURN"},{"source":17,"target":19,"value":"METHOD"},{"source":19,"target":20,"value":"RETURN"},{"source":17,"target":5,"value":"METHOD"},{"source":5,"target":10,"value":"RETURN"},{"source":17,"target":11,"value":"METHOD"},{"source":11,"target":8,"value":"RETURN"},{"source":17,"target":14,"value":"CONSTRUCTOR"},{"source":14,"target":10,"value":"PARAMETER"},{"source":14,"target":20,"value":"PARAMETER"},{"source":14,"target":20,"value":"PARAMETER"},{"source":14,"target":10,"value":"PARAMETER"},{"source":17,"target":9,"value":"SUPER"}],"nodes":[{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.METHOD","name":"METHOD","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.CONSTRUCTOR","name":"CONSTRUCTOR","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.text","name":"text","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.CLASS","name":"CLASS","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.RETURN","name":"RETURN","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":2,"id":"i2f.relation.javacode.data.JavaNodeType.text() -\u003e public java.lang.String i2f.relation.javacode.data.JavaNodeType.text()","name":"text","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":2,"id":"i2f.relation.javacode.data.JavaNodeType.valueOf() -\u003e public static i2f.relation.javacode.data.JavaNodeType i2f.relation.javacode.data.JavaNodeType.valueOf(java.lang.String)","name":"valueOf","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.EXCEPTION","name":"EXCEPTION","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":0,"id":"[Li2f.relation.javacode.data.JavaNodeType;","name":"JavaNodeType[]","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":5,"id":"java.lang.Enum","name":"Enum","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":0,"id":"java.lang.String","name":"String","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":2,"id":"i2f.relation.javacode.data.JavaNodeType.$values() -\u003e private static i2f.relation.javacode.data.JavaNodeType[] i2f.relation.javacode.data.JavaNodeType.$values()","name":"$values","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.code","name":"code","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.INTERFACE","name":"INTERFACE","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":3,"id":"i2f.relation.javacode.data.JavaNodeType.\u003cinit\u003e() -\u003e private i2f.relation.javacode.data.JavaNodeType(int,java.lang.String)","name":"i2f.relation.javacode.data.JavaNodeType","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.FIELD","name":"FIELD","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":4,"id":"java.lang.Cloneable","name":"Cloneable","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":0,"id":"i2f.relation.javacode.data.JavaNodeType","name":"JavaNodeType","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.PARAMETER","name":"PARAMETER","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":2,"id":"i2f.relation.javacode.data.JavaNodeType.code() -\u003e public int i2f.relation.javacode.data.JavaNodeType.code()","name":"code","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":0,"id":"int","name":"int","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":4,"id":"java.io.Serializable","name":"Serializable","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.ANNOTATION","name":"ANNOTATION","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":2,"id":"i2f.relation.javacode.data.JavaNodeType.values() -\u003e public static i2f.relation.javacode.data.JavaNodeType[] i2f.relation.javacode.data.JavaNodeType.values()","name":"values","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":5,"id":"java.lang.Object","name":"Object","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.$VALUES","name":"$VALUES","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0},{"category":1,"id":"i2f.relation.javacode.data.JavaNodeType.SUPER","name":"SUPER","symbolSize":20.0,"value":0.0,"x":0.0,"y":0.0}]}


    var app = new Vue({
        el: '#app',
        data: {
            graphJson: '',
            defaultOption: {
                title: {
                    text: 'Code Graph',
                    top: 'top',
                    left: 'left'
                },
                tooltip: {},
                toolbox: {
                    show: true,
                    feature: {
                        dataView: {readOnly: false},
                        restore: {},
                        saveAsImage: {}
                    }
                },
                legend: [
                    {
                        // selectedMode: 'single',
                        data: defaultGraph.categories.map(function (a) {
                            return a.name;
                        }),
                        bottom: '3%',
                        left: 'center'
                    }
                ],
                animationDuration: 1500,
                animationEasingUpdate: 'quinticInOut',
                series: [
                    {
                        name: 'Code Map',
                        type: 'graph',
                        layout: 'force',
                        // layout: 'circular',
                        // circular: {
                        //     rotateLabel: true
                        // },
                        draggable: true,
                        data: defaultGraph.nodes,
                        links: defaultGraph.links,
                        categories: defaultGraph.categories,
                        roam: true,
                        zoom: 1,
                        label: {
                            show: true,
                            position: 'right',
                        },
                        // labelLayout: {
                        //     hideOverlap: true
                        // },
                        edgeSymbol: ['circle', 'arrow'],
                        edgeSymbolSize: [4, 10],
                        edgeLabel: {
                            show: true,
                            fontSize: 10,
                            formatter: '{c}'
                        },
                        lineStyle: {
                            color: 'source',
                            curveness: 0.3
                        },
                        force: {
                            edgeLength: 5,
                            repulsion: 20,
                            gravity: 0.2
                        },
                        legendHoverLink: false,
                        emphasis: {
                            focus: 'adjacency',
                            lineStyle: {
                                width: 10
                            }
                        },
                        select:{
                            disabled: false,
                        },
                        selectedMode: 'multiple'
                    }
                ]
            },
        },
        mounted() {
            this.graphJson = JSON.stringify(defaultGraph, null, '    ')
            this.onLoadLastState()
            this.renderChart()
        },
        created() {

        },
        methods: {
            onLoadLastState() {
                let json = localStorage.getItem('echarts-graph')
                if (json) {
                    try {
                        let obj = JSON.parse(json)
                        Object.keys(obj).forEach(key => {
                            this[key] = obj[key]
                        })
                    } catch (e) {

                    }
                }
                this.renderChart()
            },
            onClearLastState() {
                localStorage.removeItem('echarts-graph')
                window.location.reload()
            },
            parseAsEchartsGraphOptions(graphJson) {
                const graph=JSON.parse(graphJson)
                graph.nodes.forEach(function (node) {
                    node.symbolSize = 24;
                });
                const option={
                    title: {
                        text: 'Code Graph',
                        top: 'top',
                        left: 'left'
                    },
                    tooltip: {},
                    toolbox: {
                        show: true,
                        feature: {
                            dataView: {readOnly: false},
                            restore: {},
                            saveAsImage: {}
                        }
                    },
                    legend: [
                        {
                            // selectedMode: 'single',
                            data: graph.categories.map(function (a) {
                                return a.name;
                            }),
                            bottom: '3%',
                            left: 'center'
                        }
                    ],
                    animationDuration: 1500,
                    animationEasingUpdate: 'quinticInOut',
                    series: [
                        {
                            name: 'Code Map',
                            type: 'graph',
                            layout: 'force',
                            // layout: 'circular',
                            // circular: {
                            //     rotateLabel: true
                            // },
                            draggable: true,
                            data: graph.nodes,
                            links: graph.links,
                            categories: graph.categories,
                            roam: true,
                            zoom: 0.05,
                            label: {
                                show: true,
                                position: 'right',
                            },
                            // labelLayout: {
                            //     hideOverlap: true
                            // },
                            edgeSymbol: ['circle', 'arrow'],
                            edgeSymbolSize: [4, 10],
                            edgeLabel: {
                                show: true,
                                fontSize: 10,
                                formatter: '{c}'
                            },
                            lineStyle: {
                                color: 'source',
                                curveness: 0.3
                            },
                            force: {
                                edgeLength: 5,
                                repulsion: 20,
                                gravity: 0.2
                            },
                            legendHoverLink: false,
                            emphasis: {
                                focus: 'adjacency',
                                lineStyle: {
                                    width: 10
                                }
                            },
                            select:{
                                disabled: false,
                            },
                            selectedMode: 'multiple'
                        }
                    ]
                }
                return option
            },
            setOption(echartsId, option, callback, clear = false) {
                // 基于准备好的dom，初始化echarts实例
                let _this = this
                let echarts = this.$echarts
                let renderFunc = function (echartsObj) {
                    if (clear) {
                        echartsObj.clear()
                    }
                    echartsObj.setOption(option)
                    if (callback) {
                        callback(echartsObj)
                    }
                }
                let ensureFunc = function () {
                    let echartsObj = null

                    let dom = document.getElementById(echartsId);
                    if (dom != null && dom != undefined) {
                        echartsObj = echarts.init(dom, 'custom')
                    }

                    if (echartsObj == null || echartsObj == undefined) {
                        setTimeout(ensureFunc, 30)
                    } else {
                        renderFunc(echartsObj)
                    }
                }
                ensureFunc()
            },
            renderChart() {
                let domId = 'chart'
                let option = this.parseAsEchartsGraphOptions(this.graphJson)
                this.setOption(domId, option, null, true)

                let json = JSON.stringify(this.$data, null, '    ')
                localStorage.setItem('echarts-graph', json)
            }
        }
    })

</script>
</html>